package com.bestv.search.management.datasyn;

import com.bestv.search.common.dataSource.DataSourceKey;
import com.bestv.search.common.dataSource.DataSourceKeyUtil;
import com.bestv.search.common.model.Info;
import com.bestv.search.common.model.Program;
import com.bestv.search.common.util.StringConst;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author Michael Wang
 */

// $Id$
public class VisDbProgramOfflineSyncer extends ProgramSyncerImpl {

    final static String sDBDriver = "oracle.jdbc.driver.OracleDriver";

    final static int singleVod = 1000;

    String orclUrl = null;
    String encoding = "ISO8859_1";
    String user = null;
    String pass = null;
    String programView = null;
    String[] activeStatusArray;

    public VisDbProgramOfflineSyncer(Map<String, String> p) throws Exception {
        this.setProps(p);
        justDoIt();
    }

    public boolean init(Map<String, String> properties) {
        if (!initLastSyncTime(StringConst.BESTV_VIS, 1, StringConst.VIS_PROGRAM_OFFLINE_SYNC_TIME)) {
            return false;
        }

        if (props.get("orclUrl") == null || props.get("orclUrl").length() == 0) {
            logger.error("orclUrl is empty!");
            result = false;
            return false;
        }
        if (props.get("program") == null || props.get("program").length() == 0) {
            logger.error("program view is empty!");
            result = false;
            return false;
        }
        if (props.get("encoding") == null || props.get("encoding").length() == 0) {
            logger.warn("encoding is empty, use ISO8859_1");
        } else {
            encoding = props.get("encoding");
        }
        orclUrl = props.get("orclUrl");
        user = props.get("user");
        pass = props.get("pass");
        programView = props.get("program");
        activeStatusArray = props.get("activeStatus").split("_");
        return true;
    }

    public boolean updateProgram() throws Exception {
        logger.info("Now proceed offline program in search's db.");
        thisSyncTime = lastSyncSuccessfullTime;

        Connection conn = null;
        ResultSet rs = null;
        Statement stmt = null;

        String syncMessage = "Success sync program offline from Vis system @ " + new Date();
        try {
            Class.forName(sDBDriver);
            conn = DriverManager.getConnection(orclUrl, user, pass);
            stmt = conn.createStatement();

            String activeStatusConditions = "";
            for (int k = 0; k < activeStatusArray.length; k++) {
                if (k == 0) {
                    activeStatusConditions = " (active_status != " + activeStatusArray[k];
                } else {
                    activeStatusConditions += " and active_status != " + activeStatusArray[k];
                }

                if (k == (activeStatusArray.length - 1)) {
                    activeStatusConditions += ") or ";
                }
            }

            rs = stmt.executeQuery("select * from " + programView + " where (" + activeStatusConditions
                    + " status=0) and " + " update_time >= to_date('" + timeformat.format(lastSyncSuccessfullTime)
                    + "','YYYY-MM-DD HH24:MI:SS') order by update_time");
            logger.info("A new batch begins at program_offline_time " + timeformat.format(lastSyncSuccessfullTime));

            int index = 0;
            List<Info> offlinePrograms = new ArrayList<Info>();
            DataSourceKey dsKey = DataSourceKeyUtil.convert(systemCache.getLocalDataSourceKey());
            while (rs.next()) {
                Date now = new Date();
                try {
                    Date ut = rs.getTimestamp("update_time");
                    if (thisSyncTime == null || ut.after(thisSyncTime)) {
                        thisSyncTime = ut;
                    }
                    List<Program> pl = pm.getProgramByCode(dsKey, rs.getString("code"));
                    if (pl != null && pl.size() > 0) {
                        for (int x = 0; x < pl.size(); x++) {
                            Program pg = pl.get(x);
                            pg.setUpdateFlag(2);
                            pg.setUpdateTimeForIndex(now);
                            pg.setUpdateTimeMillis(Long.valueOf(updatetimeformat.format(ut)));
                            offlinePrograms.add(pg);
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    logger.error("read program error! pcode=" + rs.getString("code"));
                }
                index++;
            }
            logger.info("This batch of " + index + " records ends at offline_update_time " + thisSyncTime);
            vm.saveUpdateInfoList(dsKey, offlinePrograms);

            // Update InfoHeaders' updateTime and status
            infoHeaderCommand.updateInfoHeadersTimeAndStatus(offlinePrograms);
        } catch (Exception e) {
            System.out.println(e);
            syncMessage = "Failed sync program offline from Vis system @ " + new Date();
            result = false;
            throw e;
        } finally {
            if (rs != null)
                rs.close();
            if (stmt != null)
                stmt.close();
            if (conn != null)
                conn.close();

            // Update Sync status.
            updateSyncStatus(StringConst.BESTV_VIS, 1, StringConst.VIS_PROGRAM_OFFLINE_SYNC_TIME, syncMessage,
                    thisSyncTime);
        }
        return true;
    }
}
